home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
lisp
/
kcl
/
akcl
/
kcl.lha
/
c
/
gbc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-06-04
|
22KB
|
1,108 lines
/*
(c) Copyright Taiichi Yuasa and Masami Hagiya, 1984. All rights reserved.
Copying of this file is authorized to users who have executed the true and
proper "License Agreement for Kyoto Common LISP" with SIGLISP.
*/
/*
GBC.c
IMPLEMENTATION-DEPENDENT
*/
#define DEBUG
#include "include.h"
bool saving_system;
#define round_up(n) (((n) + 03) & ~03)
char *copy_relblock();
#ifdef AV
#ifdef ATT3B2
#define page(p) (((int)(char *)(p)-0x80800000)>>PAGEWIDTH)
#define pagetochar(x) ((char *)(((x) << PAGEWIDTH) + 0x80800000))
#else
#define page(p) ((int)(char *)(p)>>PAGEWIDTH)
#define pagetochar(x) ((char *)((x) << PAGEWIDTH))
#endif
#endif
#ifdef MV
#endif
int real_maxpage;
int new_holepage;
#define available_pages \
(real_maxpage-page(heap_end)-new_holepage-2*nrbpage-real_maxpage/32)
struct apage {
char apage_self[PAGESIZE];
};
char *heap_end;
char *core_end;
#define inheap(pp) ((char *)(pp) < heap_end)
int maxpage;
object siVnotify_gbc;
#ifdef DEBUG
bool debug;
object siVgbc_message;
#endif
#define MARK_ORIGIN_MAX 300
#define MARK_ORIGIN_BLOCK_MAX 20
#ifdef AV
/*
See bitop.c.
*/
#endif
#ifdef MV
#endif
#define symbol_marked(x) ((x)->d.m)
object *mark_origin[MARK_ORIGIN_MAX];
int mark_origin_max;
struct {
object *mob_addr; /* mark origin block address */
int mob_size; /* mark origin block size */
} mark_origin_block[MARK_ORIGIN_BLOCK_MAX];
int mark_origin_block_max;
int *mark_table;
enum type what_to_collect;
bool GBC_enable;
enter_mark_origin(p)
object *p;
{
if (mark_origin_max >= MARK_ORIGIN_MAX)
error("too many mark origins");
mark_origin[mark_origin_max++] = p;
}
enter_mark_origin_block(p, n)
object *p;
int n;
{
if (mark_origin_block_max >= MARK_ORIGIN_BLOCK_MAX)
error("too many mark origin blocks");
mark_origin_block[mark_origin_block_max].mob_addr = p;
mark_origin_block[mark_origin_block_max++].mob_size = n;
}
mark_cons(x)
object x;
{
#ifdef AV
if ((int *)(&x) < cs_limit)
#endif
#ifdef MV
#endif
error("control stack overflow in GBC");
/* x is already marked. */
BEGIN:
if (x->c.c_car == OBJNULL)
;
else if (type_of(x->c.c_car) == t_cons) {
if (x->c.c_car->c.m)
;
else {
x->c.c_car->c.m = TRUE;
mark_cons(x->c.c_car);
}
} else
mark_object(x->c.c_car);
x = x->c.c_cdr;
if (x == OBJNULL)
return;
if (type_of(x) == t_cons) {
if (x->c.m)
return;
x->c.m = TRUE;
goto BEGIN;
}
if (x == Cnil)
return;
mark_object(x);
}
mark_object(x)
object x;
{
int i, j;
object *p;
char *cp;
object y;
#ifdef AV
if ((int *)(&x) < cs_limit)
#endif
#ifdef MV
#endif
error("control stack overflow in GBC");
BEGIN:
if (x == OBJNULL)
return;
if (x->d.m)
return;
x->d.m = TRUE;
switch (type_of(x)) {
case t_fixnum:
break;
case t_bignum:
BIGNUM:
x = (object)(x->big.big_cdr);
if ((struct bignum *)x == NULL)
break;
x->d.m = TRUE;
goto BIGNUM;
case t_ratio:
mark_object(x->rat.rat_num);
x = x->rat.rat_den;
goto BEGIN;
case t_shortfloat:
break;
case t_longfloat:
break;
case t_complex:
mark_object(x->cmp.cmp_imag);
x = x->cmp.cmp_real;
goto BEGIN;
case t_character:
break;
case t_symbol:
mark_object(x->s.s_plist);
mark_object(x->s.s_gfdef);
mark_object(x->s.s_dbind);
if (x->s.s_self == NULL)
break;
if ((int)what_to_collect >= (int)t_contiguous) {
if (inheap(x->s.s_self)) {
if (what_to_collect == t_contiguous)
mark_contblock(x->s.s_self,
x->s.s_fillp);
} else
x->s.s_self =
copy_relblock(x->s.s_self, x->s.s_fillp);
}
break;
case t_package:
mark_object(x->p.p_name);
mark_object(x->p.p_nicknames);
mark_object(x->p.p_shadowings);
mark_object(x->p.p_uselist);
mark_object(x->p.p_usedbylist);
if (what_to_collect != t_contiguous)
break;
if (x->p.p_internal != NULL)
mark_contblock((char *)(x->p.p_internal),
PHTABSIZE*sizeof(object));
if (x->p.p_external != NULL)
mark_contblock((char *)(x->p.p_external),
PHTABSIZE*sizeof(object));
break;
case t_cons:
/*
mark_object(x->c.c_car);
x = x->c.c_cdr;
goto BEGIN;
*/
mark_cons(x);
break;
case t_hashtable:
mark_object(x->ht.ht_rhsize);
mark_object(x->ht.ht_rhthresh);
if (x->ht.ht_self == NULL)
break;
for (i = 0, j = x->ht.ht_size; i < j; i++) {
mark_object(x->ht.ht_self[i].hte_key);
mark_object(x->ht.ht_self[i].hte_value);
}
if ((short)what_to_collect >= (short)t_contiguous) {
if (inheap(x->ht.ht_self)) {
if (what_to_collect == t_contiguous)
mark_contblock((char *)(x->ht.ht_self),
j * sizeof(struct htent));
} else
x->ht.ht_self = (struct htent *)
copy_relblock((char *)(x->ht.ht_self),
j * sizeof(struct htent));
}
break;
case t_array:
if ((y = x->a.a_displaced) != Cnil) {
/* BUG FIX for marking first word of displaced */
/* By Nick Gall */
y->c.m = TRUE;
mark_object(y->c.c_car);
for (y = y->c.c_cdr; y != Cnil; y = y->c.c_cdr)
y->c.m = TRUE;
}
if ((int)what_to_collect >= (int)t_contiguous &&
x->a.a_dims != NULL) {
if (inheap(x->a.a_dims)) {
if (what_to_collect == t_contiguous)
mark_contblock((char *)(x->a.a_dims),
sizeof(int)*x->a.a_rank);
} else
x->a.a_dims = (int *)
copy_relblock((char *)(x->a.a_dims),
sizeof(int)*x->a.a_rank);
}
if ((enum aelttype)x->a.a_elttype == aet_ch)
goto CASE_STRING;
if ((enum aelttype)x->a.a_elttype == aet_bit)
goto CASE_BITVECTOR;
if ((enum aelttype)x->a.a_elttype == aet_object)
goto CASE_GENERAL;
CASE_SPECIAL:
cp = (char *)(x->fixa.fixa_self);
if (cp == NULL)
break;
if ((enum aelttype)x->a.a_elttype == aet_lf)
j = sizeof(longfloat)*x->lfa.lfa_dim;
else
j = sizeof(fixnum)*x->fixa.fixa_dim;
goto COPY;
CASE_GENERAL:
p = x->a.a_self;
if (p == NULL)
break;
if (x->a.a_displaced->c.c_car == Cnil)
for (i = 0, j = x->a.a_dim; i < j; i++)
mark_object(p[i]);
cp = (char *)p;
j *= sizeof(object);
COPY:
if ((int)what_to_collect >= (int)t_contiguous) {
if (inheap(cp)) {
if (what_to_collect == t_contiguous)
mark_contblock(cp, j);
} else if (x->a.a_displaced == Cnil)
x->a.a_self = (object *)copy_relblock(cp, j);
else if (x->a.a_displaced->c.c_car == Cnil) {
i = (int)(object *)copy_relblock(cp, j)
- (int)(x->a.a_self);
adjust_displaced(x, i);
}
}
break;
case t_vector:
if ((y = x->v.v_displaced) != Cnil) {
/* BUG FIX for marking first word of displaced */
/* By Nick Gall */
y->c.m = TRUE;
mark_object(y->c.c_car);
for (y = y->c.c_cdr; y != Cnil; y = y->c.c_cdr)
y->c.m = TRUE;
}
if ((enum aelttype)x->v.v_elttype == aet_object)
goto CASE_GENERAL;
else
goto CASE_SPECIAL;
CASE_STRING:
case t_string:
if ((y = x->st.st_displaced) != Cnil) {
/* BUG FIX for marking first word of displaced */
/* By Nick Gall */
y->c.m = TRUE;
mark_object(y->c.c_car);
for (y = y->c.c_cdr; y != Cnil; y = y->c.c_cdr)
y->c.m = TRUE;
}
j = x->st.st_dim;
cp = x->st.st_self;
if (cp == NULL)
break;
COPY_STRING:
if ((int)what_to_collect >= (int)t_contiguous) {
if (inheap(cp)) {
if (what_to_collect == t_contiguous)
mark_contblock(cp, j);
} else if (x->st.st_displaced == Cnil)
x->st.st_self = copy_relblock(cp, j);
else if (x->st.st_displaced->c.c_car == Cnil) {
i = copy_relblock(cp, j) - cp;
adjust_displaced(x, i);
}
}
break;
CASE_BITVECTOR:
case t_bitvector:
if ((y = x->bv.bv_displaced) != Cnil) {
/* BUG FIX for marking first word of displaced */
/* By Nick Gall */
y->c.m = TRUE;
mark_object(y->c.c_car);
for (y = y->c.c_cdr; y != Cnil; y = y->c.c_cdr)
y->c.m = TRUE;
}
j = (x->bv.bv_offset + x->bv.bv_dim + 7)/8;
cp = x->bv.bv_self;
if (cp == NULL)
break;
goto COPY_STRING;
case t_structure:
mark_object(x->str.str_name);
p = x->str.str_self;
if (p == NULL)
break;
for (i = 0, j = x->str.str_length; i < j; i++)
mark_object(p[i]);
if ((int)what_to_collect >= (int)t_contiguous) {
if (inheap(x->str.str_self)) {
if (what_to_collect == t_contiguous)
mark_contblock((char *)p,
j*sizeof(object));
} else
x->str.str_self = (object *)
copy_relblock((char *)p, j*sizeof(object));
}
break;
case t_stream:
switch (x->sm.sm_mode) {
case smm_input:
case smm_output:
case smm_io:
case smm_probe:
mark_object(x->sm.sm_object0);
mark_object(x->sm.sm_object1);
if (what_to_collect == t_contiguous &&
x->sm.sm_fp != NULL &&
x->sm.sm_fp->_base != NULL &&
x->sm.sm_fp->_base != BASEFF)
mark_contblock(x->sm.sm_fp->_base, BUFSIZ);
break;
case smm_synonym:
mark_object(x->sm.sm_object0);
break;
case smm_broadcast:
case smm_concatenated:
mark_object(x->sm.sm_object0);
break;
case smm_two_way:
case smm_echo:
mark_object(x->sm.sm_object0);
mark_object(x->sm.sm_object1);
break;
case smm_string_input:
case smm_string_output:
mark_object(x->sm.sm_object0);
break;
default:
error("mark stream botch");
}
break;
case t_random:
break;
case t_readtable:
if (x->rt.rt_self == NULL)
break;
if (what_to_collect == t_contiguous)
mark_contblock((char *)(x->rt.rt_self),
RTABSIZE*sizeof(struct rtent));
for (i = 0; i < RTABSIZE; i++) {
mark_object(x->rt.rt_self[i].rte_macro);
if (x->rt.rt_self[i].rte_dtab != NULL) {
/**/
if (what_to_collect == t_contiguous)
mark_contblock((char *)(x->rt.rt_self[i].rte_dtab),
RTABSIZE*sizeof(object));
for (j = 0; j < RTABSIZE; j++)
mark_object(x->rt.rt_self[i].rte_dtab[j]);
/**/
}
}
break;
case t_pathname:
mark_object(x->pn.pn_host);
mark_object(x->pn.pn_device);
mark_object(x->pn.pn_directory);
mark_object(x->pn.pn_name);
mark_object(x->pn.pn_type);
mark_object(x->pn.pn_version);
break;
case t_cfun:
mark_object(x->cf.cf_name);
mark_object(x->cf.cf_data);
if (x->cf.cf_start == NULL)
break;
if (what_to_collect == t_contiguous) {
if (get_mark_bit((int *)(x->cf.cf_start)))
break;
mark_contblock(x->cf.cf_start, x->cf.cf_size);
}
break;
case t_cclosure:
mark_object(x->cc.cc_name);
mark_object(x->cc.cc_env);
mark_object(x->cc.cc_data);
if (x->cc.cc_start == NULL)
break;
if (what_to_collect == t_contiguous) {
if (get_mark_bit((int *)(x->cc.cc_start)))
break;
mark_contblock(x->cc.cc_start, x->cc.cc_size);
if (x->cc.cc_turbo != NULL) {
for (i = 0, y = x->cc.cc_env;
type_of(y) == t_cons;
i++, y = y->c.c_cdr);
mark_contblock((char *)(x->cc.cc_turbo),
i*sizeof(object));
}
}
break;
case t_spice:
break;
default:
#ifdef DEBUG
if (debug)
printf("\ttype = %d\n", type_of(x));
#endif
error("mark botch");
}
}
mark_phase()
{
STATIC object *p;
STATIC int i, j, k, n;
STATIC struct package *pp;
STATIC object s, l, *lp;
STATIC bds_ptr bdp;
STATIC frame_ptr frp;
STATIC ihs_ptr ihsp;
STATIC char *cp;
mark_object(Cnil);
mark_object(Ct);
for (p = vs_org; p < vs_top; p++) {
mark_object(*p);
}
#ifdef DEBUG
if (debug) {
printf("value stack marked\n");
fflush(stdout);
}
#endif
for (bdp = bds_org; bdp<=bds_top; bdp++) {
mark_object(bdp->bds_sym);
mark_object(bdp->bds_val);
}
for (frp = frs_org; frp <= frs_top; frp++)
mark_object(frp->frs_val);
for (ihsp = ihs_org; ihsp <= ihs_top; ihsp++)
mark_object(ihsp->ihs_function);
for (i = 0; i < mark_origin_max; i++)
mark_object(*mark_origin[i]);
for (i = 0; i < mark_origin_block_max; i++)
for (j = 0; j < mark_origin_block[i].mob_size; j++)
mark_object(mark_origin_block[i].mob_addr[j]);
for (pp = pack_pointer; pp != NULL; pp = pp->p_link)
mark_object(pp);
#ifdef DEBUG
if (debug) {
printf("symbol navigation\n");
fflush(stdout);
}
#endif
/*
if (what_to_collect != t_symbol &&
(int)what_to_collect < (int)t_contiguous) {
*/
for (pp = pack_pointer; pp != NULL; pp = pp->p_link) {
if (pp->p_internal != NULL)
for (i = 0; i < PHTABSIZE; i++)
mark_object(pp->p_internal[i]);
if (pp->p_external != NULL)
for (i = 0; i < PHTABSIZE; i++)
mark_object(pp->p_external[i]);
}
/*
The following code is now in the comment.
Interned symbols are never collocted.
return;
}
for (pp = pack_pointer; pp != NULL; pp = pp->p_link) {
if (pp->p_internal != NULL)
for (i = 0; i < PHTABSIZE; i++)
for (l=pp->p_internal[i]; !endp(l); l=l->c.c_cdr) {
s = l->c.c_car;
if (symbol_marked(s) ||
s->s.s_hpack == (object)pp &&
s->s.s_plist == Cnil &&
s->s.s_sfdef == NOT_SPECIAL &&
s->s.s_gfdef == OBJNULL &&
s->s.s_dbind == OBJNULL &&
s->s.s_stype == (short)stp_ordinary &&
s->s.s_mflag == FALSE)
;
else
mark_object(s);
}
if (pp->p_external != NULL)
for (i = 0; i < PHTABSIZE; i++)
mark_object(pp->p_external[i]);
}
for (pp = pack_pointer; pp != NULL; pp = pp->p_link)
if (pp->p_internal != NULL)
for (i = 0; i < PHTABSIZE; i++)
for (lp = &(pp->p_internal[i]); !endp(*lp);) {
s = (*lp)->c.c_car;
if (!symbol_marked(s))
*lp = (*lp)->c.c_cdr;
else {
(*lp)->d.m = TRUE;
lp = &((*lp)->c.c_cdr);
}
}
*/
}
sweep_phase()
{
STATIC int i, j, k;
STATIC object x;
STATIC char *p;
STATIC int *ip;
STATIC struct typemanager *tm;
STATIC object f;
Cnil->s.m = FALSE;
Ct->s.m = FALSE;
#ifdef DEBUG
if (debug)
printf("type map\n");
#endif
for (i = 0; i < maxpage; i++) {
if (type_map[i] == (int)t_contiguous) {
if (debug) {
printf("-");
/*
fflush(stdout);
*/
continue;
}
}
if (type_map[i] >= (int)t_end)
continue;
tm = tm_of((enum type)type_map[i]);
/*
general sweeper
*/
#ifdef DEBUG
if (debug) {
printf("%c", tm->tm_name[0]);
/*
fflush(stdout);
*/
}
#endif
p = pagetochar(i);
f = tm->tm_free;
k = 0;
for (j = tm->tm_nppage; j > 0; --j, p += tm->tm_size) {
x = (object)p;
if (x->d.m == FREE)
continue;
else if (x->d.m) {
x->d.m = FALSE;
continue;
}
switch (x->d.t) {
case t_array:
case t_vector:
case t_string:
case t_bitvector:
if (x->a.a_displaced->c.c_car != Cnil)
undisplace(x);
}
((struct freelist *)x)->f_link = f;
x->d.m = FREE;
f = x;
k++;
}
tm->tm_free = f;
tm->tm_nfree += k;
tm->tm_nused -= k;
NEXT_PAGE:
;
}
#ifdef DEBUG
if (debug) {
putchar('\n');
fflush(stdout);
}
#endif
}
contblock_sweep_phase()
{
STATIC int i, j;
STATIC char *s, *e, *p, *q;
STATIC struct contblock *cbp;
cb_pointer = NULL;
ncb = 0;
for (i = 0; i < maxpage;) {
if (type_map[i] != (int)t_contiguous) {
i++;
continue;
}
for (j = i+1;
j < maxpage && type_map[j] == (int)t_contiguous;
j++)
;
s = pagetochar(i);
e = pagetochar(j);
for (p = s; p < e;) {
if (get_mark_bit((int *)p)) {
p += 4;
continue;
}
q = p + 4;
while (q < e) {
if (!get_mark_bit((int *)q)) {
q += 4;
continue;
}
break;
}
insert_contblock(p, q - p);
p = q + 4;
}
i = j + 1;
}
#ifdef DEBUG
if (debug) {
for (cbp = cb_pointer; cbp != NULL; cbp = cbp->cb_link)
printf("%d-byte contblock\n", cbp->cb_size);
fflush(stdout);
}
#endif
}
int (*GBC_enter_hook)() = NULL;
int (*GBC_exit_hook)() = NULL;
GBC(t)
enum type t;
{
int i, j;
struct apage *pp, *qq;
#ifdef DEBUG
int tm;
#endif
if (siVnotify_gbc->s.s_dbind != Cnil) {
fprintf(stdout, "\nGBC invoked");
fflush(stdout);
}
if (GBC_enter_hook != NULL)
(*GBC_enter_hook)();
if (!GBC_enable)
error("GBC is not enabled");
interrupt_enable = FALSE;
if (saving_system)
t = t_contiguous;
#ifdef DEBUG
debug = symbol_value(siVgbc_message) != Cnil;
#endif
what_to_collect = t;
if (t == t_contiguous)
cbgbccount++;
else if (t == t_relocatable)
rbgbccount++;
else
tm_table[(int)t].tm_gbccount++;
#ifdef DEBUG
if (debug) {
if (t == t_contiguous)
printf("GBC entered for collecting contiguous blocks\n");
else if (t == t_relocatable)
printf("GBC entered for collecting relocatable blocks\n");
else
printf("GBC entered for collecting %s\n",
tm_table[(int)t].tm_name);
fflush(stdout);
}
#endif
maxpage = page(heap_end);
if ((int)t >= (int)t_contiguous) {
j = maxpage*16;
/*
1 page = 512 long word
512 bit = 16 long word
*/
if (t == t_relocatable)
j = 0;
if (holepage < new_holepage)
holepage = new_holepage;
i = rb_pointer - rb_start;
if (nrbpage > (real_maxpage-page(heap_end)
-holepage-real_maxpage/32)/2) {
if (i > nrbpage*PAGESIZE)
error("Can't allocate. Good-bye!.");
else
nrbpage =
(real_maxpage-page(heap_end)
-holepage-real_maxpage/32)/2;
}
if (saving_system)
rb_start = heap_end;
else
rb_start = heap_end + PAGESIZE*holepage;
rb_end = rb_start + PAGESIZE*nrbpage;
if (rb_start < rb_pointer)
rb_start1 = (char *)
((int)(rb_pointer + PAGESIZE-1) & -PAGESIZE);
else
rb_start1 = rb_start;
rb_pointer = rb_start;
rb_pointer1 = rb_start1;
mark_table = (int *)(rb_start1 + i);
if (rb_end < (char *)&mark_table[j])
i = (char *)&mark_table[j] - heap_end;
else
i = rb_end - heap_end;
alloc_page(-(i + PAGESIZE - 1)/PAGESIZE);
for (i = 0; i < j; i++)
mark_table[i] = 0;
}
#ifdef DEBUG
if (debug) {
printf("mark phase\n");
fflush(stdout);
tm = runtime();
}
#endif
mark_phase();
#ifdef DEBUG
if (debug) {
printf("mark ended (%d)\n", runtime() - tm);
fflush(stdout);
}
#endif
#ifdef DEBUG
if (debug) {
printf("sweep phase\n");
fflush(stdout);
tm = runtime();
}
#endif
sweep_phase();
#ifdef DEBUG
if (debug) {
printf("sweep ended (%d)\n", runtime() - tm);
fflush(stdout);
}
#endif
if (t == t_contiguous) {
#ifdef DEBUG
if (debug) {
printf("contblock sweep phase\n");
fflush(stdout);
tm = runtime();
}
#endif
contblock_sweep_phase();
#ifdef DEBUG
if (debug)
printf("contblock sweep ended (%d)\n",
runtime() - tm);
#endif
}
if ((int)t >= (int)t_contiguous) {
if (rb_start < rb_start1) {
j = (rb_pointer-rb_start + PAGESIZE - 1)/PAGESIZE;
pp = (struct apage *)rb_start;
qq = (struct apage *)rb_start1;
for (i = 0; i < j; i++)
*pp++ = *qq++;
}
rb_limit = rb_end - 2*RB_GETA;
}
#ifdef DEBUG
if (debug) {
for (i = 0, j = 0; i < (int)t_end; i++) {
if (tm_table[i].tm_type == (enum type)i) {
printf("%13s: %8d used %8d free %4d/%d pages\n",
tm_table[i].tm_name,
tm_table[i].tm_nused,
tm_table[i].tm_nfree,
tm_table[i].tm_npage,
tm_table[i].tm_maxpage);
j += tm_table[i].tm_npage;
} else
printf("%13s: linked to %s\n",
tm_table[i].tm_name,
tm_table[(int)tm_table[i].tm_type].tm_name);
}
printf("contblock: %d blocks %d pages\n", ncb, ncbpage);
printf("hole: %d pages\n", holepage);
printf("relblock: %d bytes used %d bytes free %d pages\n",
rb_pointer - rb_start, rb_end - rb_pointer, nrbpage);
printf("GBC ended\n");
fflush(stdout);
}
#endif
interrupt_enable = TRUE;
if (saving_system) {
j = (rb_pointer-rb_start+PAGESIZE-1) / PAGESIZE;
heap_end += PAGESIZE*j;
core_end = heap_end;
for (i = 0; i < maxpage; i++)
if ((enum type)type_map[i] == t_contiguous)
type_map[i] = (char)t_other;
cb_pointer = NULL;
maxcbpage -= ncbpage;
ncbpage = 0;
ncb = 0;
holepage = new_holepage;
nrbpage -= j;
if (nrbpage <= 0)
error("no relocatable pages left");
rb_start = heap_end + PAGESIZE*holepage;
rb_end = rb_start + PAGESIZE*nrbpage;
rb_limit = rb_end - 2*RB_GETA;
rb_pointer = rb_start;
}
if (GBC_exit_hook != NULL)
(*GBC_exit_hook)();
if (siVnotify_gbc->s.s_dbind != Cnil) {
fprintf(stdout, "\nGBC finished\n");
fflush(stdout);
}
}
siLroom_report()
{
int i;
check_arg(0);
/*
GBC(t_contiguous);
*/
vs_check_push(make_fixnum(real_maxpage));
vs_push(make_fixnum(available_pages));
vs_push(make_fixnum(ncbpage));
vs_push(make_fixnum(maxcbpage));
vs_push(make_fixnum(ncb));
vs_push(make_fixnum(cbgbccount));
vs_push(make_fixnum(holepage));
vs_push(make_fixnum(rb_pointer - rb_start));
vs_push(make_fixnum(rb_end - rb_pointer));
vs_push(make_fixnum(nrbpage));
vs_push(make_fixnum(rbgbccount));
for (i = 0; i < (int)t_end; i++) {
if (tm_table[i].tm_type == (enum type)i) {
vs_check_push(make_fixnum(tm_table[i].tm_nused));
vs_push(make_fixnum(tm_table[i].tm_nfree));
vs_push(make_fixnum(tm_table[i].tm_npage));
vs_push(make_fixnum(tm_table[i].tm_maxpage));
vs_push(make_fixnum(tm_table[i].tm_gbccount));
} else {
vs_check_push(Cnil);
vs_push(make_fixnum(tm_table[i].tm_type));
vs_push(Cnil);
vs_push(Cnil);
vs_push(Cnil);
}
}
}
siLreset_gbc_count()
{
int i;
check_arg(0);
cbgbccount = 0;
rbgbccount = 0;
for (i = 0; i < (int)t_end; i++)
tm_table[i].tm_gbccount = 0;
}
char *
copy_relblock(p, s)
char *p;
int s;
{
STATIC char *q, *e;
s = round_up(s);
e = p + s;
q = rb_pointer1;
while (p < e)
*q++ = *p++;
q = rb_pointer;
rb_pointer += s;
rb_pointer1 += s;
return(q);
}
mark_contblock(p, s)
char *p;
int s;
{
STATIC char *q;
STATIC int *x, *y;
if ((enum type)type_map[page(p)] != t_contiguous)
return;
q = p + s;
x = (int *)(char *)((int)p&~3);
y = (int *)(char *)(((int)q+3)&~3);
for (; x < y; x++)
set_mark_bit(x);
}
Lgbc()
{
check_arg(1);
if (vs_base[0] == Ct)
GBC(t_contiguous);
else if (vs_base[0] == Cnil)
GBC(t_cons);
else
GBC(t_relocatable);
}
init_GBC()
{
make_si_function("ROOM-REPORT", siLroom_report);
make_si_function("RESET-GBC-COUNT", siLreset_gbc_count);
siVnotify_gbc = make_si_special("*NOTIFY-GBC*", Cnil);
#ifdef DEBUG
siVgbc_message = make_si_special("*GBC-MESSAGE*", Cnil);
#endif
make_function("GBC", Lgbc);
}